hvm: local_events_need_delivery() should take notice of EFLAGS.IF.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Wed, 4 Apr 2007 18:17:39 +0000 (19:17 +0100)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Wed, 4 Apr 2007 18:17:39 +0000 (19:17 +0100)
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/hvm/irq.c
xen/include/asm-x86/event.h

index aa531b33fb520af37fc75c86ab78a6840f245974..a85151eb267c81c87b68ae540b05b3eea4f1afa7 100644 (file)
@@ -337,6 +337,25 @@ int is_isa_irq_masked(struct vcpu *v, int isa_irq)
             domain_vioapic(v->domain)->redirtbl[gsi].fields.mask);
 }
 
+/*
+ * TODO: 1. Should not need special treatment of event-channel events.
+ *       2. Should take notice of interrupt shadows (or clear them).
+ */
+int hvm_local_events_need_delivery(struct vcpu *v)
+{
+    int pending;
+
+    pending = (vcpu_info(v, evtchn_upcall_pending) || cpu_has_pending_irq(v));
+    if ( unlikely(pending) )
+    {
+        struct cpu_user_regs regs;
+        hvm_store_cpu_guest_regs(v, &regs, NULL);
+        pending = !irq_masked(regs.eflags);
+    }
+
+    return pending;
+}
+
 #if 0 /* Keep for debugging */
 static void irq_dump(struct domain *d)
 {
index 09440bcc4a5526b0ecf3fa6b68b22804745d0486..32b157b8db94842c9bcc31529f91a1fef323a434 100644 (file)
@@ -35,12 +35,13 @@ static inline void vcpu_mark_events_pending(struct vcpu *v)
         vcpu_kick(v);
 }
 
+int hvm_local_events_need_delivery(struct vcpu *v);
 static inline int local_events_need_delivery(void)
 {
     struct vcpu *v = current;
-    return ((vcpu_info(v, evtchn_upcall_pending) &&
-             !vcpu_info(v, evtchn_upcall_mask)) ||
-            (is_hvm_vcpu(v) && cpu_has_pending_irq(v)));
+    return (is_hvm_vcpu(v) ? hvm_local_events_need_delivery(v) :
+            (vcpu_info(v, evtchn_upcall_pending) &&
+             !vcpu_info(v, evtchn_upcall_mask)));
 }
 
 static inline int local_event_delivery_is_enabled(void)